<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: dark)"><meta name="generator" content="Hexo 5.2.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" integrity="sha256-xejo6yLi6vGtAjcMIsY8BHdKsLg7QynVlFMzdQgUuy8=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css" integrity="sha256-Vzbj7sDDS/woiFS3uNKo8eIuni59rjyNGtXfstRzStA=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"gz1234.gitee.io","root":"/","images":"/images","scheme":"Gemini","darkmode":true,"version":"8.12.3","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"flat"},"bookmark":{"enable":true,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="state 如何注入组件，从 redux 到组件经历的过程react 最新的生命周期React 16 之后有三个⽣命周期被废弃(但并未删除)  componentWillMount componentWillReceiveProps componentWillUpdate计划在 17 版本完全删除这三个函数，只保留 UNSAVE_前缀的三个函数，⽬的是为了向下兼容，但是对于开发者⽽⾔应该尽量避免使">
<meta property="og:type" content="article">
<meta property="og:title" content="react面试题">
<meta property="og:url" content="https://gz1234.gitee.io/2020/10/29/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/react%E9%9D%A2%E8%AF%95%E9%A2%98/index.html">
<meta property="og:site_name" content="郭泽">
<meta property="og:description" content="state 如何注入组件，从 redux 到组件经历的过程react 最新的生命周期React 16 之后有三个⽣命周期被废弃(但并未删除)  componentWillMount componentWillReceiveProps componentWillUpdate计划在 17 版本完全删除这三个函数，只保留 UNSAVE_前缀的三个函数，⽬的是为了向下兼容，但是对于开发者⽽⾔应该尽量避免使">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2020-10-29T03:05:28.000Z">
<meta property="article:modified_time" content="2023-04-27T01:11:48.142Z">
<meta property="article:author" content="郭泽">
<meta property="article:tag" content="react面试题">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="https://gz1234.gitee.io/2020/10/29/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/react%E9%9D%A2%E8%AF%95%E9%A2%98/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://gz1234.gitee.io/2020/10/29/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/react%E9%9D%A2%E8%AF%95%E9%A2%98/","path":"2020/10/29/前端面试题/react面试题/","title":"react面试题"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>react面试题 | 郭泽</title>
  





  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">郭泽</p>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#state-%E5%A6%82%E4%BD%95%E6%B3%A8%E5%85%A5%E7%BB%84%E4%BB%B6%EF%BC%8C%E4%BB%8E-redux-%E5%88%B0%E7%BB%84%E4%BB%B6%E7%BB%8F%E5%8E%86%E7%9A%84%E8%BF%87%E7%A8%8B"><span class="nav-number">1.</span> <span class="nav-text">state 如何注入组件，从 redux 到组件经历的过程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#react-%E6%9C%80%E6%96%B0%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"><span class="nav-number">2.</span> <span class="nav-text">react 最新的生命周期</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#setState-%E6%98%AF%E5%90%8C%E6%AD%A5%E8%BF%98%E6%98%AF%E5%BC%82%E6%AD%A5"><span class="nav-number">3.</span> <span class="nav-text">setState 是同步还是异步</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#react-%E7%BB%84%E4%BB%B6%E7%9A%84%E9%80%9A%E4%BF%A1"><span class="nav-number">4.</span> <span class="nav-text">react 组件的通信</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#react-%E4%BC%98%E5%8C%96%E6%89%8B%E6%AE%B5"><span class="nav-number">5.</span> <span class="nav-text">react 优化手段</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%AE%B2-%E4%B8%80-%E4%B8%8B-react-fiber%EF%BC%9F"><span class="nav-number">6.</span> <span class="nav-text">讲 一 下 react fiber？</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#redux-%E5%92%8C-mobx-%E7%9A%84-%E5%8C%BA-%E5%88%AB-%E5%92%8C-%E4%BD%BF-%E7%94%A8-%E5%9C%BA-%E6%99%AF"><span class="nav-number">7.</span> <span class="nav-text">redux 和 mobx 的 区 别 和 使 用 场 景</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%B8%B8-%E7%94%A8-%E7%9A%84-react-hooks-%E6%96%B9-%E6%B3%95"><span class="nav-number">8.</span> <span class="nav-text">常 用 的 react hooks 方 法</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#useState-%E6%80%8E-%E4%B9%88-%E5%81%9A-%E7%BC%93-%E5%AD%98-%E7%9A%84"><span class="nav-number">9.</span> <span class="nav-text">useState 怎 么 做 缓 存 的</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#react-ssr-%E6%98%AF-%E5%9C%A8-%E4%BB%80-%E4%B9%88-%E5%9C%BA-%E6%99%AF-%E4%B8%8B-%E5%81%9A-%E7%9A%84-%EF%BC%9F"><span class="nav-number">10.</span> <span class="nav-text">react ssr 是 在 什 么 场 景 下 做 的 ？</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#react-ssr-%E5%8F%8C-%E7%AB%AF-%E6%80%8E-%E4%B9%88-%E5%81%9A-%E6%9E%84-%E5%BB%BA-%E7%9A%84-%EF%BC%9F-%E5%8C%BA-%E5%88%AB-%E5%9C%A8-%E5%93%AA-%E9%87%8C-%EF%BC%9F"><span class="nav-number">11.</span> <span class="nav-text">react ssr 双 端 怎 么 做 构 建 的 ？ 区 别 在 哪 里 ？</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#render-%E5%92%8C-renderToString-%E7%9A%84-%E5%BA%95-%E5%B1%82-%E5%AE%9E-%E7%8E%B0-%E4%B8%8A-%E7%9A%84-%E5%8C%BA-%E5%88%AB-%EF%BC%9F"><span class="nav-number">12.</span> <span class="nav-text">render 和 renderToString 的 底 层 实 现 上 的 区 别 ？</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#react-ssr-%E5%92%8C-ejs-%E6%80%A7-%E8%83%BD-%E7%9A%84-%E5%B7%AE-%E5%BC%82-%EF%BC%9F"><span class="nav-number">13.</span> <span class="nav-text">react ssr 和 ejs 性 能 的 差 异 ？</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#useRef-%E4%B8%8E-createRef-%E5%8C%BA%E5%88%AB"><span class="nav-number">14.</span> <span class="nav-text">useRef 与 createRef 区别</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#React-Fiber-%E6%98%AF%E4%BB%80%E4%B9%88"><span class="nav-number">15.</span> <span class="nav-text">React Fiber 是什么?</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Fiber-%E5%87%BA%E7%8E%B0%E7%9A%84%E8%83%8C%E6%99%AF"><span class="nav-number">15.1.</span> <span class="nav-text">Fiber 出现的背景</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Fiber-%E6%98%AF%E4%BB%80%E4%B9%88"><span class="nav-number">15.2.</span> <span class="nav-text">Fiber 是什么</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Fiber-%E6%98%AF%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%9F"><span class="nav-number">15.3.</span> <span class="nav-text">Fiber 是如何解决问题的？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Fiber-%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86"><span class="nav-number">15.4.</span> <span class="nav-text">Fiber 实现原理</span></a></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">郭泽</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">54</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">21</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">51</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>
  <a role="button" class="book-mark-link book-mark-link-fixed"></a>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://gz1234.gitee.io/2020/10/29/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/react%E9%9D%A2%E8%AF%95%E9%A2%98/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="郭泽">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="郭泽">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="react面试题 | 郭泽">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          react面试题
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2020-10-29 11:05:28" itemprop="dateCreated datePublished" datetime="2020-10-29T11:05:28+08:00">2020-10-29</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2023-04-27 09:11:48" itemprop="dateModified" datetime="2023-04-27T09:11:48+08:00">2023-04-27</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/" itemprop="url" rel="index"><span itemprop="name">前端面试题</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/react/" itemprop="url" rel="index"><span itemprop="name">react</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <h2 id="state-如何注入组件，从-redux-到组件经历的过程"><a href="#state-如何注入组件，从-redux-到组件经历的过程" class="headerlink" title="state 如何注入组件，从 redux 到组件经历的过程"></a>state 如何注入组件，从 redux 到组件经历的过程</h2><h2 id="react-最新的生命周期"><a href="#react-最新的生命周期" class="headerlink" title="react 最新的生命周期"></a>react 最新的生命周期</h2><p>React 16 之后有三个⽣命周期被废弃(但并未删除)</p>
<ul>
<li>componentWillMount</li>
<li>componentWillReceiveProps</li>
<li>componentWillUpdate<br>计划在 17 版本完全删除这三个函数，只保留 UNSAVE_前缀的三个函数，⽬的是为了向下兼容，但是对于开发者⽽⾔应该尽量避免使⽤他们，⽽是使⽤新增的⽣命周期函数替代它们</li>
</ul>
<p>最新的⽣命周期分为三个阶段,分别是挂载阶段、更新阶段、卸载阶段</p>
<ul>
<li>挂载阶段<ul>
<li>constructor: 构造函数，最先被执⾏,我们通常在构造函数⾥初始化 state 对象或者给⾃定义⽅法绑定 this</li>
<li>getDerivedStateFromProps: static getDerivedStateFromProps(nextProps, prevState) ,这是个静态⽅法,当我们接收到新的属性想去修改我们 state，可以使⽤ getDerivedStateFromProps</li>
<li>render: render 函数是纯函数，只返回需要渲染的东⻄，不应该包含其它的业务逻辑,可以返回原⽣的 DOM、React 组件、Fragment、Portals、字符串和数字、Boolean 和 null 等内容</li>
<li>componentDidMount: 组件装载之后调⽤，此时我们可以获取到 DOM 节点并操作，⽐如对 canvas，svg 的操作，服务器请求，订阅都可以写在这个⾥⾯，但是记得在 componentWillUnmount 中取消订阅</li>
</ul>
</li>
<li>更新阶段<ul>
<li>getDerivedStateFromProps: 此⽅法在更新个挂载阶段都可能会调⽤</li>
<li>shouldComponentUpdate: shouldComponentUpdate(nextProps, nextState) ,有两个参数 nextProps 和 nextState，表示新的属性和变化之后的 state，返回⼀个布尔值，true 表示会触发重新渲染，false 表示不会触发重新渲染，默认返回 true,我们通常利⽤此⽣命周期来优化 React 程序性能</li>
<li>render: 更新阶段也会触发此⽣命周期</li>
<li>getSnapshotBeforeUpdate: getSnapshotBeforeUpdate(prevProps, prevState) , 这 个 ⽅ 法 在 render 之 后 ，componentDidUpdate 之前调⽤，有两个参数 prevProps 和 prevState，表示之前的属性和之前的 state，这个函数有⼀个返回值，会作为第三个参数传给 componentDidUpdate，如果你不想要返回值，可以返回 null，此⽣命周期必须与 componentDidUpdate 搭配使⽤</li>
<li>componentDidUpdate: componentDidUpdate(prevProps, prevState, snapshot) ,该⽅法在 getSnapshotBeforeUpdate ⽅法之后被调⽤，有三个参数 prevProps，prevState，snapshot，表示之前的 props，之前的 state，和 snapshot。第三个参数是 getSnapshotBeforeUpdate 返回的,如果触发某些回调函数时需要⽤到 DOM 元素的状态，则将对⽐或计算的过程迁移⾄ getSnapshotBeforeUpdate，然后在 componentDidUpdate 中统⼀触发回调或更新状态。</li>
</ul>
</li>
<li>卸载阶段</li>
</ul>
<h2 id="setState-是同步还是异步"><a href="#setState-是同步还是异步" class="headerlink" title="setState 是同步还是异步"></a>setState 是同步还是异步</h2><h2 id="react-组件的通信"><a href="#react-组件的通信" class="headerlink" title="react 组件的通信"></a>react 组件的通信</h2><h2 id="react-优化手段"><a href="#react-优化手段" class="headerlink" title="react 优化手段"></a>react 优化手段</h2><h2 id="讲-一-下-react-fiber？"><a href="#讲-一-下-react-fiber？" class="headerlink" title="讲 一 下 react fiber？"></a>讲 一 下 react fiber？</h2><ul>
<li><p>React 通过Fiber 架构，让这个执⾏过程变成可被中断。“适时”地让出 CPU 执⾏权，除了可以让浏<br>览器及时地响应⽤户的交互，还有其他好处:<br>●分批延时对DOM进⾏操作，避免⼀次性操作⼤量 DOM 节点，可以得到更好的⽤户体验；<br>●给浏览器⼀点喘息的机会，它会对代码进⾏编译优化（JIT）及进⾏热代码优化，或者对 reflow 进⾏修<br>正。</p>
</li>
<li><p>Fiber 也称协程或者纤程。它和线程并不⼀样，协程本身是没有并发或者并⾏能⼒的（需要配<br>合线程），它只是⼀种控制流程的让出机制。让出 CPU 的执⾏权，让 CPU 能在这段时间执⾏其他的操<br>作。渲染的过程可以被中断，可以将控制权交回浏览器，让位给⾼优先级的任务，浏览器空闲后再恢复<br>渲染。</p>
</li>
</ul>
<h2 id="redux-和-mobx-的-区-别-和-使-用-场-景"><a href="#redux-和-mobx-的-区-别-和-使-用-场-景" class="headerlink" title="redux 和 mobx 的 区 别 和 使 用 场 景"></a>redux 和 mobx 的 区 别 和 使 用 场 景</h2><h2 id="常-用-的-react-hooks-方-法"><a href="#常-用-的-react-hooks-方-法" class="headerlink" title="常 用 的 react hooks 方 法"></a>常 用 的 react hooks 方 法</h2><h2 id="useState-怎-么-做-缓-存-的"><a href="#useState-怎-么-做-缓-存-的" class="headerlink" title="useState 怎 么 做 缓 存 的"></a>useState 怎 么 做 缓 存 的</h2><h2 id="react-ssr-是-在-什-么-场-景-下-做-的-？"><a href="#react-ssr-是-在-什-么-场-景-下-做-的-？" class="headerlink" title="react ssr 是 在 什 么 场 景 下 做 的 ？"></a>react ssr 是 在 什 么 场 景 下 做 的 ？</h2><h2 id="react-ssr-双-端-怎-么-做-构-建-的-？-区-别-在-哪-里-？"><a href="#react-ssr-双-端-怎-么-做-构-建-的-？-区-别-在-哪-里-？" class="headerlink" title="react ssr 双 端 怎 么 做 构 建 的 ？ 区 别 在 哪 里 ？"></a>react ssr 双 端 怎 么 做 构 建 的 ？ 区 别 在 哪 里 ？</h2><h2 id="render-和-renderToString-的-底-层-实-现-上-的-区-别-？"><a href="#render-和-renderToString-的-底-层-实-现-上-的-区-别-？" class="headerlink" title="render 和 renderToString 的 底 层 实 现 上 的 区 别 ？"></a>render 和 renderToString 的 底 层 实 现 上 的 区 别 ？</h2><h2 id="react-ssr-和-ejs-性-能-的-差-异-？"><a href="#react-ssr-和-ejs-性-能-的-差-异-？" class="headerlink" title="react ssr 和 ejs 性 能 的 差 异 ？"></a>react ssr 和 ejs 性 能 的 差 异 ？</h2><h2 id="useRef-与-createRef-区别"><a href="#useRef-与-createRef-区别" class="headerlink" title="useRef 与 createRef 区别"></a>useRef 与 createRef 区别</h2><p>createRef 每次渲染都会返回一个新的引用，而 useRef 每次都会返回相同的引用。</p>
<h2 id="React-Fiber-是什么"><a href="#React-Fiber-是什么" class="headerlink" title="React Fiber 是什么?"></a>React Fiber 是什么?</h2><h3 id="Fiber-出现的背景"><a href="#Fiber-出现的背景" class="headerlink" title="Fiber 出现的背景"></a>Fiber 出现的背景</h3><p>首先要知道的是，JS 引擎和页面渲染引擎两个线程是互斥的，当其中一个线程执行时，另一个线程只能挂起等待。在这样的机制下，如果 JS 线程长时间地占用了主线程，那么渲染层面的更新就不得不长时间地等待，界面长时间不更新，会导致页面响应度变差，用户可能会感觉到卡顿<br>而这正是 React15 的 Stack Reconciler 所面临的问题，即是 JS 对主线程的超时占用问题。Stack Reconciler 是一个同步的递归过程，使用的是 JS 引擎自身的函数调用栈，它会一直执行到栈空为止，所以当 React 在渲染组件时，从开始到渲染完成整个过程是一气呵成的。如果渲染的组件比较庞大，JS 执行会占据主线程较长时间，会导致页面响应度变差。而且所有的任务都是按照先后顺序，没有区分优先级，这样就会导致优先级比较高的任务无法被优先执行</p>
<h3 id="Fiber-是什么"><a href="#Fiber-是什么" class="headerlink" title="Fiber 是什么"></a>Fiber 是什么</h3><p>Fiber 与进程、线程同为程序执行过程，Fiber 就是比线程还要纤细的一个过程，意味着在对渲染过程进行更加精细的控制<br>从架构角度老看，Fiber 是对 React 核心算法(即调和过程)的重写<br>从编码角度来看，Fiber 是 React 内部所定义的一种数据结构，它是 Fiber 树结构的节点单位，也就是 React 16 新架构下的虚拟 DOM</p>
<h3 id="Fiber-是如何解决问题的？"><a href="#Fiber-是如何解决问题的？" class="headerlink" title="Fiber 是如何解决问题的？"></a>Fiber 是如何解决问题的？</h3><p>Fiber 把一个渲染任务分解为多个渲染任务，而不是一次性完成，把每一个分割得很细得任务视作一个执行单元，React 就会检查现在还剩多少时间，如果没有时间就将控制权让出去，故任务会被分散到多个帧里面，中间可以返回至主程控制执行其他任务，最终实现更流畅的用户体验。<br>即实现了增量渲染，实现可中断与恢复，恢复后也可以复用之前的中间状态，并给不同的任务赋予不同的优先级，其中每个任务更新单元为 React Element 对应的 Fiber 节点</p>
<h3 id="Fiber-实现原理"><a href="#Fiber-实现原理" class="headerlink" title="Fiber 实现原理"></a>Fiber 实现原理</h3><p>实现的方式是 requestIdleCallback 这一 api，但 React 团队 polyfill 了这个 api，使其对比原生的浏览器兼容性更好且扩展了这个特性。requestIdleCallback 回调的执行前提条件是当前浏览器处于空闲状态。即 requestIdleCallback 的作用是在浏览器一帧的剩余空闲时间内执行优先度相对较低的任务。</p>
<p>首先 React 中任务切割为多个步骤，分批完成。在完成一部分任务之后，将控制权交回浏览器，让浏览器有时间在进行页面的渲染。等浏览器忙完之后有剩余时间，在继续之前 React 未完成的任务，是一种合作式调度。简而言之，由浏览器给我们分配执行时间片，我们要按照约定在这个时间内执行完毕，并将控制权交还给浏览器。React16 的 Reconciler 基于 Fiber 节点实现，被称为 Fiber Reconciler</p>
<p>作为静态的数据结构来说，每个 Fiber 节点对应一个 React element，保存该组件的类型(函数组件、类组件、原生组件等等)，对应的 DOM 节点等信息</p>
<p>作为动态的工作单元来说，每个 Fiber 节点保存本次更新中该组件改变的状态、要执行的工作。每个 Fiber 节点有个对应的 React element，多个 Fiber 节点是如何形成树的呢？靠下面的三个属性：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F;指向父级Fiber节点</span><br><span class="line">this.return &#x3D; null;</span><br><span class="line">&#x2F;&#x2F; 指向子Fiber节点</span><br><span class="line">this.child &#x3D; null;</span><br><span class="line">&#x2F;&#x2F; 指向右边第一个兄弟Fiber节点</span><br><span class="line">this.sibling &#x3D; null;</span><br></pre></td></tr></table></figure>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kity@2.0.4/dist/kity.min.js"></script><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kityminder-core@1.4.50/dist/kityminder.core.min.js"></script><script defer="true" type="text/javascript" src="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.js"></script><link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.css">
    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/react%E9%9D%A2%E8%AF%95%E9%A2%98/" rel="tag"># react面试题</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2020/10/29/%E6%B5%8F%E8%A7%88%E5%99%A8%E8%B0%83%E8%AF%95%E6%8A%80%E5%B7%A7/" rel="prev" title="浏览器调试技巧">
                  <i class="fa fa-chevron-left"></i> 浏览器调试技巧
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/2020/10/29/js-codeSnippet/" rel="next" title="js 代码片段实现">
                  js 代码片段实现 <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2023</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">郭泽</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js" integrity="sha256-yt2kYMy0w8AbtF89WXb2P1rfjcP/HTHLT7097U8Y5b8=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/bookmark.js"></script>

  
<script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.0/search.js" integrity="sha256-vXZMYLEqsROAXkEw93GGIvaB2ab+QW6w3+1ahD9nXXA=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>

  <script class="next-config" data-name="pdf" type="application/json">{"object_url":{"url":"https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.2.8/pdfobject.min.js","integrity":"sha256-tu9j5pBilBQrWSDePOOajCUdz6hWsid/lBNzK4KgEPM="},"url":"/lib/pdf/web/viewer.html"}</script>
  <script src="/js/third-party/tags/pdf.js"></script>

  <script class="next-config" data-name="mermaid" type="application/json">{"enable":true,"theme":{"light":"default","dark":"dark"},"js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mermaid/9.1.3/mermaid.min.js","integrity":"sha256-TIYL00Rhw/8WaoUhYTLX9SKIEFdXxg+yMWSLVUbhiLg="}}</script>
  <script src="/js/third-party/tags/mermaid.js"></script>

  <script src="/js/third-party/fancybox.js"></script>


  





</body>
</html>
